package com.yuelife.market.service.impl;

import com.yuelife.market.dao.MProductDao;
import com.yuelife.market.dao.UserDao;
import com.yuelife.market.entity.GoodsCondition;
import com.yuelife.market.entity.MProduct;
import com.yuelife.market.entity.User;
import com.yuelife.market.service.MProductService;
import com.yuelife.market.utils.AliyunossUtils;
import com.yuelife.market.utils.FileUploadResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * (MProduct)表服务实现类
 *
 * @author makejava
 * @since 2020-06-11 23:05:04
 */
@Service
public class MProductServiceImpl implements MProductService {
    @Autowired
    private MProductDao mProductDao;
    @Autowired
    private AliyunossUtils ali;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserDao userDao;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public MProduct queryById(Integer id) {
        return this.mProductDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Override
    public List<MProduct> queryAllByLimit(int offset, int limit) {
        return this.mProductDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param mProduct 实例对象
     * @return 实例对象
     */
    @Override
    public Map insert(MProduct mProduct, MultipartFile file) {

          //上传到本地磁盘
//        File pathFile=new File("f:/upload");
//        //判断这个路径下是否存在文件，如果不存在，则创建一个
//        if (!pathFile.exists()){
//            pathFile.mkdirs();
//        }
//        //文件名
//        String fileName=file.getOriginalFilename();
//        //取得扩展名
//        String ext=fileName.substring(fileName.lastIndexOf("."));
//        //重命名  使用时间毫秒
//        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMddhhmmss");
//        //自定义文件名称
//        String newFileName=simpleDateFormat.format(new Date());
//        //文件归档  File.separator这个是分隔符
//        try {
//            file.transferTo(new File("f:/upload"+File.separator+newFileName+ext));
//            System.out.println("我是图片名称："+newFileName+ext);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        //存储状态码和商品编号(UUID)，返回给前端，前端得到商品编号用在上传多张图片的时候
        Map map=new HashMap();
        //上传到阿里云,会返回文件访问路径
        try {
            FileUploadResult uploadResult= ali.upload(file);
            //获取当前回复时间
            Date date=new Date();
            //时间格式
            SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String da=timeFormat.format(date);
            //生成UUID
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            //创建商品时间
            mProduct.setCreateTime(da);
            //创建商品编号
            mProduct.setProductSn(uuid);
            //图片访问路径
            mProduct.setPic(uploadResult.getName());
            //创建商品
            this.mProductDao.insert(mProduct);
            //并且存放到redis       做错了，发布的商品，未能通过则不能放在redis里面
//            redisTemplate.opsForHash().put("myProductList",mProduct.getProductSn(),mProduct);
            //状态码
            map.put("code",200);
            map.put("data",uuid);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code",500);
            return map;
        }
    }

    /**
     * 修改数据
     *
     * @param mProduct 实例对象
     * @return 实例对象
     */
    @Override
    public MProduct update(MProduct mProduct) {
        this.mProductDao.update(mProduct);
        return this.queryById(mProduct.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.mProductDao.deleteById(id) > 0;
    }

    /**
     * 查询所有商品
     * @return
     */
//    @Override
//    public List<MProduct> selectAllProduct(GoodsCondition goodsCondition) {
////        //先在redis里面取所有商品数据，
////        List<MProduct> listProduct=redisTemplate.opsForList().range("listProduct",0,-1);
////        if (listProduct==null||listProduct.size()<=0){
////            //如果redis里面没有数据，那么就在数据库查询，然后放到redis里面
////            List<MProduct> mProducts= mProductDao.selectAllProduct(goodsCondition);
////            redisTemplate.opsForList().leftPush("listProduct",mProducts);
////            System.out.println("我只有第一次出现，因为我不在redis中，第二次不会出现");
////            //再一次取值
////            listProduct=redisTemplate.opsForList().range("listProduct",0,-1);
////        }
////        System.out.println(listProduct);
////        return listProduct;
//
//        //这是存储在map中
//        List<MProduct> mProductList= (List<MProduct>) redisTemplate.opsForHash().entries("myProductList");
//        if (mProductList==null||mProductList.size()<=0){
//            List<MProduct> mProducts= mProductDao.selectAllProduct(goodsCondition);
//            System.out.println("我只有第一次出现，因为我不在redis中，第二次不会出现");
//            for (MProduct m:mProducts){
//                redisTemplate.opsForHash().put("myProductList",m.getProductSn(),mProductList);
//            }
//            mProductList=(List<MProduct>) redisTemplate.opsForHash().entries("myProductList");
//        }
//        return mProductList;
//
//    }


    @Override
    public Map selectAllProduct(GoodsCondition goodsCondition) {
        //这是存储在map中
        Map mProductList=  redisTemplate.opsForHash().entries("myProductList");
        if (mProductList==null||mProductList.size()<=0){
//            List<MProduct> mProducts= mProductDao.selectAllProduct(goodsCondition);
            List<MProduct> mProducts= mProductDao.selectAllProduct();
            System.out.println("我只有第一次出现，因为我不在redis中，第二次不会出现");
            for (MProduct m:mProducts){
                redisTemplate.opsForHash().put("myProductList",m.getProductSn(),m);
            }
            mProductList= redisTemplate.opsForHash().entries("myProductList");
        }
        return mProductList;

    }

    @Override
    public List<MProduct> conditionData(GoodsCondition goodsCondition) {
        return mProductDao.conditionData(goodsCondition);
    }


    /**
     * 搜索商品
     * @return
     */
    @Override
    public List<MProduct> selectProductBySearch(MProduct mProduct) {
        return mProductDao.selectProductBySearch(mProduct);
    }

    /**
     * 查看商品详情，根据商品编号
     * @param productSn
     * @return
     */
    @Override
    @Cacheable(value = "productDetails",key = "#productSn")
    public MProduct selectProductBySn(String productSn) {
        System.out.println("如果redis没有，那么我会出现，我只会第一次出现");
        return mProductDao.selectProductBySn(productSn);
    }

    /**
     * 收藏数增加
     * @param productsn
     */
    @Override
    @CachePut(value ="productDetails",key ="#productsn")//redis缓存中的商品详情也会被修改
    //这个注解每次都会操作数据库，不管缓存有没有
    public MProduct addlikes(String productsn) {
        mProductDao.addLikes(productsn);
        MProduct m=mProductDao.selectProductBySn(productsn);
        redisTemplate.opsForHash().put("myProductList",productsn,m);
        return m;
    }

    /**
     * 收藏减少
     * @param productSn
     */
    @Override
    @CachePut(value ="productDetails",key ="#productSn")//redis缓存中的商品详情也会被修改
    //这个注解每次都会操作数据库，不管缓存有没有
    public MProduct reduceLikes(String productSn) {
        mProductDao.reduceLikes(productSn);
        MProduct m=mProductDao.selectProductBySn(productSn);
        redisTemplate.opsForHash().put("myProductList",productSn,m);
        return m;
    }

    /**
     * 查询商品总数
     * @return
     */
    @Override
    public Long selectCount() {
        return mProductDao.selectCount();
    }



    /**
     * 在创建订单的时候，订单页展示商品信息和用户信息
     * @param productSn
     * @return
     */
    @Override
    public MProduct selectProductAndUser(String productSn) {
        return mProductDao.selectProductAndUser(productSn);
    }

    //微服务调用过来的，商品审核过后，在redis中添加一条数据
    @Override
    public void updataRedisProduct(MProduct mProduct) {
        if (mProduct!=null){
            redisTemplate.opsForHash().put("myProductList",mProduct.getProductSn(),mProduct);
        }
    }

    //微服务调用的，在后台删除商品过后，需要把redis中商品列表的数据删除
    @Override
    public void deleteRedisProduct(String productSn) {
        if (productSn!=null){
            redisTemplate.opsForHash().delete("myProductList",productSn);
        }

    }

    @Override
    public User selectTelephone(String productSn) {
        MProduct mProduct=mProductDao.selectProductBySn(productSn);
        //得到商品创建者id
        Integer id=mProduct.getCreatorSn();
        //得到卖家信息
        return userDao.queryById(id);

    }

    //修改商品状态
    @Override
    public void updateStatusByProductSn(String zfbOrderSn, int i) {
        mProductDao.updateStatusByProductSn(zfbOrderSn, i);
    }
}